#ifndef __RING_BUF__
#define __RING_BUF__
#include "stdint.h"
#include "string.h"
template<typename T1>
class RingBuf
{
private:
	uint16_t Read, Write, Size;
	T1* Memory;
protected:

public:
	typedef enum
	{
		RingBuf_Empty = 0,
		RingBuf_NotEmpty,
		RingBuf_Full,
		RingBuf_Error
	} RingBuf_Status_t; //状态类型

	RingBuf(uint16_t _Size);//分配内存
	~RingBuf();//回收内存

	bool WriteElement(T1* Data, uint16_t Number = 1);//写入一个或多个元素
	bool WriteElement(T1 Data);//写入一个元素,非引用传递
	bool ReadElement(T1* Data, uint16_t Number = 1);//读出一个或多个元素,读出后数据删除
	bool ReadElement(T1& Data);//读出一个元素
	bool PeekElement(T1* Data, uint16_t Number = 1);//读取数据但不从队列中删除

	T1& operator [](uint16_t Index)//重载数组运算符
	{
		return Memory[((Read + Index) % (Size + 1))];
	}
	void Clear()//快速清空队列
	{
		Read = Write;
	}
	uint16_t GetRaminSpace()//获取剩余空间
	{
		//w>r rim = (s-1)-w+r;
		//w<r rim = (r-1)-w;
		return (Write < Read) ? (Read - 1 - Write) : (Size - Write + Read);
	}
	uint16_t GetDataNumber()//获取数据数量
	{
		//w>r Dn = w-r;
		//w<r Dn = (s-1)-r+w+1
		return (Write < Read) ? (Size - Read + Write + 1) : (Write - Read);
	}
	RingBuf_Status_t Status()//获取状态
	{
		if (this->is_Empty()) //空
			return RingBuf_Empty;
		else if (this->is_Full()) //满
			return RingBuf_Full;
		else if (Size != 0) //有内存,且有数据
			return RingBuf_NotEmpty;
		else//没有内存
			return RingBuf_Error;
	}
	bool is_Empty()
	{
		return (Read == Write);//读写指针相接,代表队列空
	}
	bool is_Full()
	{
		return ((Read - 1) == Write);//写入达到读取的上一个空间,意味着队列满
	}
};
template<typename T1>
RingBuf<T1>::RingBuf(uint16_t _Size) :Read(0), Write(0), Size(_Size), Memory(nullptr)
{
	Memory = new T1[_Size + 1];
	if (Memory == nullptr)
	{
		Size = 0;
	}
	else
	{
		memset(Memory, 0, Size);
	}
};
template<typename T1>
RingBuf<T1>::~RingBuf()
{
	if (Size)
		delete[] Memory;
}
template<typename T1>
bool RingBuf<T1>::WriteElement(T1* Data, uint16_t Number)
{
	if (this->GetRaminSpace() < Number) //没有足够空间储存
		return false;//拒绝储存
	for (uint16_t i = 0; i < Number; i++, Write++)
	{
		Memory[Write] = Data[i];
		Write %= (Size + 1);
	}
	return true;//已经成功储存
}
template<typename T1>
bool RingBuf<T1>::WriteElement(T1 Data)
{
	if (this->GetRaminSpace() < 1) //没有足够空间储存
		return false;//拒绝储存
	Memory[Write++] = Data;
	Write %= (Size + 1);
	return true;//已经成功储存
}
template<typename T1>
bool RingBuf<T1>::ReadElement(T1* Data, uint16_t Number)
{
	if (this->is_Empty())
		return false;//无可读数据
	else if (Number > this->GetDataNumber())
		return false;//存储的数据量不足
	for (uint16_t i = 0; i < Number; i++, Read++)
	{
		Data[i] = Memory[Read];
		Read %= (Size + 1);
	}
	return true;//已经成功读取
}
template<typename T1>
bool RingBuf<T1>::ReadElement(T1& Data)
{
	if (this->is_Empty())
		return false;//无可读数据
	Data = Memory[Read++];
	Read %= (Size + 1);
	return true;//已经成功读取
}
template<typename T1>
bool RingBuf<T1>::PeekElement(T1* Data, uint16_t Number)
{
	if (this->is_Empty())
		return false;//无可读数据
	else if (Number > this->GetDataNumber())
		return false;//存储的数据量不足
	uint16_t tmRead = Read;
	for (uint16_t i = 0; i < Number; i++, tmRead++)
	{
		Data[i] = Memory[tmRead];
		tmRead %= (Size + 1);
	}
	return true;//已经成功读取
}
#endif
